package org.springframework.validation.util;

import org.springframework.binding.expression.Expression;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.definition.StateDefinition;
import org.springframework.webflow.engine.Flow;
import org.springframework.webflow.execution.RequestContext;

public class WebflowModelAccessor {
	
	public static Object getModel(RequestContext requestContext) {
		
		if (!requestContext.getFlowExecutionContext().isActive()) {
			throw new RuntimeException("Error in flow: Initial state has no " +
			"model or model name does not match input or flowscope.");
		}
		
		Flow flow = (Flow) requestContext.getActiveFlow();
		MutableAttributeMap scope = requestContext.getFlowScope();
		
		String modelString = findModelExpression(flow);
		if (modelString.contains(".")) {
			modelString = modelString.substring(modelString.lastIndexOf("."));
		}
		if (modelString != null && scope.contains(modelString)) {
			return scope.get(modelString);
		} else {
			throw new RuntimeException("Error in flow: Initial state has no " +
					"model or model name does not match input or flowscope.");
		}
	}
	
	protected static String findModelExpression(Flow flow) {
		String modelExpression = null;
		for (String stateId : flow.getStateIds()) {
			StateDefinition state = flow.getState(stateId);
			if (state.getAttributes().contains("model")) {
				modelExpression = ((Expression)state.getAttributes().get("model")).getExpressionString();
				break;
			}
		}
		return modelExpression;
	}
}
